(function() {
    Nokia.OptionsMenu = Nokia.Widget.extend({
        initialize: function(options) {
            var instance = this;

			var defaults = {
				transitions: false
			};

            instance.options = jQuery.extend(defaults, options);

            instance.element = jQuery( instance.options.element );

            instance.sections = [];

            instance._super.apply(instance, [instance.options]);

            instance._attachEvents();

            instance.registerData("optionsmenu");

			instance.registerVibrationOn([]);
			instance.fireCallback('create');
        },

        addSection: function(section) {
        	var instance = this;

        	instance.sections.push(section);
        },

        appendShadow: function() {
			var instance = this;

			var bottom = Nokia.dom.parseHTML('<div class="nokia-shadow"><div class="nokia-shadow-bottom"><div class="nokia-shadow-bc"></div></div></div>');

			instance.element.append(bottom);
		},

		_attachEvents: function() {
			var instance = this,
				options = instance.options,
				Styles = instance.Styles;

			var allowed = [
				'.' + Styles.nokiaLabel,
				'.' + Styles.labelContent,
				'.' + Styles.labelIcon
			].join(', ');

			jQuery(document.body).bind('click.optionsmenu', function(event) {
        		if (!jQuery(event.target).is(allowed)) {
        			instance.hideOptions();
        		}
        	});
		},

		_cleanSelectedItems: function(optionsContainer) {
			var instance = this;
			var Styles = instance.Styles;

			optionsContainer.find('> *').each(function(i, item) {
				Nokia.util.removeClass(item, Styles.uiStateHover);
			});
		},

		_cleanSelectedSections: function() {
			var instance = this;
			var Styles = instance.Styles;

			jQuery.each(instance.allSectionElements, function(i, sectionElement) {
				var label = jQuery(sectionElement).find('> .' + Styles.nokiaLabel);

				Nokia.util.removeClass(label[0], Styles.uiStateHover);
			});
		},

		hideOptions: function() {
			var instance = this;

			jQuery.each(instance.allOptionsContainers, function(i, optionsContainer) {
				instance._cleanSelectedItems(optionsContainer);

				optionsContainer.hide();
			});

			instance.overflow.hide();
		},

		create: function() {
			var instance = this,
				element = instance.element,
				options = instance.options,
				Styles = instance.Styles;

			var sections = instance.sections;

			var menuWrapper = Nokia.dom.parseHTML('<div class="' + [Styles.optionsmenu].join(' ') + '"></div>');

			Nokia.dom.append(element, menuWrapper);

			Nokia.util.addClass( element[0], [Styles.uiClearfix].join(' ') );

			instance.overflow = Nokia.util.createOverflow();

			instance.allOptionsContainers = [];
			instance.allSectionElements = [];

			jQuery.each(sections, function(i, section) {
				var sectionElement = Nokia.dom.parseHTML('<div href="javascript:void(0);" class="' + [Styles.optionsmenuItem, Styles.uiClearfix].join(' ') +'"></div>');
				var label = Nokia.dom.parseHTML('<a href="javascript:void(0);"></a>');
				var labelContent = Nokia.dom.parseHTML('<div class="' + [Styles.labelContent].join(' ') +'">' + section.getLabel() +'</div>');
				var labelIcon = Nokia.dom.parseHTML('<div class="' + [Styles.labelIcon].join(' ') + '"></div>');

				label.addClass([
					Styles.uiStateDefault,
					Styles.uiClearfix,
					Styles.nokiaLabel
				].join(' '));

				Nokia.dom.append(label, labelContent);
				Nokia.dom.append(label, labelIcon);
				Nokia.dom.append(sectionElement, label);

				var sectionItems = section.getItems();

				if ( sectionItems.length ) {
					var optionsContainer = Nokia.dom.parseHTML('<div class="' + [Styles.optionsContainer].join(' ') +'"></div>');

					Nokia.dom.append(sectionElement, optionsContainer);
					instance.allOptionsContainers.push(optionsContainer);
					instance.allSectionElements.push(sectionElement);

					jQuery.each(sectionItems, function(i, sectionItem) {
						var sectionItemElement = Nokia.dom.parseHTML('<a href="javascript:void(0);" class="' + [Styles.uiStateDefault].join(' ') + '">' + sectionItem.getLabel() + '</a>');

						sectionItemElement.hover(function() {
							Nokia.util.addClass(this, Styles.uiStateHover);
						}, function() {
							Nokia.util.removeClass(this, Styles.uiStateHover);
						});

						sectionItemElement.bind('click.optionsmenu', function(event) {
							// Hides parent sectionElement
							instance.hideOptions();

							// Trigger hide callback
							instance.fireCallback('hide', event);

							// Trigger callback
							sectionItem.select(event);

							// Focus parent sectionElement
							label.focus();
							Nokia.util.addClass(label[0], Styles.uiStateHover);

							return false;
						});

						Nokia.util.bindEnter(sectionItemElement, function(e) {
							sectionItemElement.trigger('click.optionsmenu');
						});

						Nokia.dom.append(optionsContainer, sectionItemElement);
					});

					label.hover(function() {
						// Clean selected state
						instance._cleanSelectedSections();

						Nokia.util.addClass(label[0], Styles.uiStateHover);
					}, function() {
						Nokia.util.removeClass(label[0], Styles.uiStateHover);
					});

					label.bind('click.optionsmenu', function(event) {

						if (optionsContainer.is(':visible')) {
							instance.hideOptions();

							if (options.transitions) {
								Nokia.animation.fadeOut(instance.overflow);
							} else {
								instance.overflow.hide();
							}

							instance.fireCallback('hide', event);
						} else {
							optionsContainer.show();

							if (options.transitions) {
								Nokia.animation.fadeIn(instance.overflow);
							} else {
								instance.overflow.show();
							}

							instance.fireCallback('show', event);
						}

						if (instance.activeOptions) {
							if (instance.activeOptions != optionsContainer) {
								instance.activeOptions.hide();
							}
						}

						instance.activeSection = sectionElement;
						instance.activeOptions = optionsContainer;
					});

					Nokia.util.bindEnter(label, function() {
						label.trigger('click.optionsmenu');
					});

				}

				sectionElement.width((100 / sections.length + '%'));

				Nokia.dom.append(menuWrapper, sectionElement);
			});

			instance.appendShadow();

			instance.hideOptions();
		},

		Styles: {
			optionsmenu: 'nokia-optionsmenu',
			optionsmenuItem: 'nokia-optionsmenu-item',
			optionsmenuItemSelected: 'nokia-optionsmenu-item-selected',
			optionsmenuContent: 'nokia-optionsmenu-content',
			optionsContainer: 'nokia-optionsmenu-optionscontainer',
			labelContent: 'nokia-optionsmenu-label-content',
			labelIcon: 'nokia-optionsmenu-label-icon',
			nokiaLabel: 'nokia-label',
			uiClearfix: 'ui-helper-clearfix',
			uiStateDefault: 'ui-state-default',
			uiStateActive: 'ui-state-active',
			uiStateHover: 'ui-state-hover',
			nokiaHidden: 'nokia-hidden'
		}
    });

     Nokia.OptionsMenuSection = Nokia.Widget.extend({
     	initialize: function(options) {
            var instance = this;

			var defaults = {
				label: 'Section'
			};

            instance.options = jQuery.extend(defaults, options);

            instance.items = [];

            instance._super.apply(instance, [instance.options]);

            instance.registerData("optionsmenusection");
        },

        addItem: function(item) {
        	var instance = this;

        	instance.items.push(item);
        },

        removeItem: function(item) {
			var instance = this;

			if (Nokia.util.isNumber(item)) {
				Nokia.util.arrayRemove(instance.items, item);
			}
			else if (item instanceof Nokia.OptionsMenuItem) {
				instance.items.splice(jQuery.inArray(item, instance.items), 1);
			}
		},

        getItems: function() {
        	var instance = this;

        	return instance.items;
        },

        getLabel: function() {
        	var instance = this;

        	return instance.options.label;
        }
     });

     Nokia.OptionsMenuItem = Nokia.Widget.extend({
     	initialize: function(options) {
            var instance = this;

			var defaults = {};

            instance.options = jQuery.extend(defaults, options);

            instance.items = [];

            instance._super.apply(instance, [instance.options]);

            instance.registerData("optionsmenuitem");
        },

        select: function(event) {
        	var instance = this;
        	var callback = instance.options.select;

        	if (callback) {
        		callback.apply(instance, [event, this]);
        	}
        },

        getLabel: function() {
        	var instance = this;

        	return instance.options.label;
        }
     });
})();